//
//  InsCcNote.swift
//  ParsingCC
//
//  Created by ins-yangming on 2023/2/28.
//

import UIKit
import SwiftyJSON

class InsCcNote: NSObject {
    var hide = false;
    var index = 0;
    var id = "";
    var step = 1;
    var octave = 0;
    var alter = 0;
    var line = 0;
    var staff = 0;
    var duration = 0.0;
    var tick = 0;
    var type = 0;
    var stemType = "";
    var y = 0;
    var x = 0.0;
    var v = 1;
    var rest = false;
    var inbeam = false;
    var beamType = [(Int , Int , Int)]();
    var tiedStart = "";
    var tiedStop = "";
    
    var accidental = "";
    
    var isChord = false;
    
    var arpeggiate = false;
    
    var fermata = false;
    
    var accent = false;
    
    var articulations = false;
    
    var invertedMordent = false;
    
    var detachedLegato = false;
    
    var trillmark = false;
    
    var string = 0;
    
    var fingeringArray = [String]();
    
    var slur = "";
    
    var slurStopx = 0.0;
    
    var tremolo = 0;
    
    var tremoloType = "";
    
    var tremoloX2 = 0.0;
    
    var wavyLine = false;
    
    var dots = 0;
    
    var chordNotes = [InsCcNote]();
    
    var word = "";
    
    var clef = "";
    
    var tuplet = 0;
    
    var normalNotes = 0;
    
    var isTupletUp = false;
    
    var tenuto = false;
    
    var shiftSize = 0;
    
    var shiftStopx = 0;
    
    var shiftX1 = 0;
    
    var shiftStaff = 0;
    
    var isShiftStart = false;
    
    var isShiftStopType = 0;
    
    var isTupletStart = false;
    
    var isTupletContinue = false;
    
    var isTupletStop = false;
    
    var isSlideStart = false;
    
    var isSlideStop = false;
    
    var isGlissandoStart = false;
    
    var isGlissandoStop = false;
    
    var glissandoStopX = 0.0;
    
    var isPedal = false;
    
    var pedalType = "";
    
    var isGraceSlash = 0;
    
    var isTurn = false;
    
    
    var metronome = "";
    
    var dynString = "";
    
    var lyrics = [(String , Double)]();
    
    var json = JSON();
    
    init(json : JSON) {
        super.init();
        self.json = json;
//        self.index = json["col"].intValue;
        self.hide = json["hide"].boolValue;
        self.x = json["x"].doubleValue;
        self.v = json["v"].intValue + 1;
//        if self.v == 0 {
//            self.v = 1;
//        }else if self.v == 1 {
//            self.v = 0;
//        }
        
        self.dots = json["dots"].intValue;
        
        self.staff = json["staff"].intValue;
       
        self.tick = json["tick"].intValue;
        self.type = json["type"].intValue;
      
        if self.type != 0 {
            self.duration = 4/Double(self.type);
        }else {
            self.duration = 8;
        }
        var duration = self.duration;
        for i in 0..<self.dots {
            duration = duration * 0.5;
            self.duration += duration;
        }
        
        if let elems = json["elems"].array {
            for (i ,elem) in elems.enumerated() {
                if i == 0 {
                    if let step = elem.dictionary?["step"]?.intValue {
                        self.step = step - 1;
                    }
                    if let octave = elem.dictionary?["octave"]?.intValue {
                        
                        self.octave = octave;
                    }
                    if let alter = elem.dictionary?["alter"]?.intValue {
                        self.alter = alter;
                    }
                    if let acc = elem.dictionary?["acc"]?.dictionary?["acc"]?.string {
                        if acc == "Flat" {
                            self.accidental = "flat";
                        }else if acc == "Sharp" {
                            self.accidental = "sharp";
                        }else if acc == "Natural" {
                            self.accidental = "natural";
                        }
                    }
                    if (elem.dictionary?["id"]?.stringValue ?? "") == "n_12_4" {
//                        print(111);
                    }
                    if let array = elem.dictionary?["pairs"]?.array {
                        for json in array {
                            if let type = json["type"].string {
                                if type == "tied" {
                                    self.tiedStart = "start";
                                }else if type == "tremolo" {
                                    self.tremolo = json["num"].intValue;
                                    let x1 = json["x1"].doubleValue;
                                    let x2 = json["x2"].doubleValue;
                                    if x1 <= self.x {
                                        self.tremoloType = "single";
                                    }else{
                                        self.tremoloType = "start";
                                        self.tremoloX2 = x2;
                                    }
                                }else if type == "wavy-line" {
                                    self.wavyLine = true;
                                }else if type == "tuplet" {
                                    self.tuplet = json["value"].intValue;
                                    self.isTupletUp = json["up"].boolValue;
                                }else if type == "slide" {
                                    self.isSlideStart = true;
                                }else if type == "slur" {
                                    self.slur = "start";
                                    let x1 = json["x1"].doubleValue;
                                    let x2 = json["x2"].doubleValue;
                                    self.slurStopx = x1 + x2 + self.x;
                                }else if type == "glissando" {
                                    self.isGlissandoStart = true;
                                    let x1 = json["x1"].doubleValue;
                                    let x2 = json["x2"].doubleValue;
                                    self.glissandoStopX = x2 + self.x;
                                }
                            }
                        }
                    }
                    
                    
                    if let tied = elem.dictionary?["tied"]?.string {
                        if tied == "end" {
                            self.tiedStop = "stop";
                        }
                    }
                    
                    if let id = elem.dictionary?["id"]?.string {
                        self.id = id;
                    }
                    if let line = elem.dictionary?["line"]?.intValue {
                        self.line = line;
                    }
                    if let y = elem.dictionary?["y"]?.intValue {
                        self.y = y;
                    }
                }else {
                    self.isChord = true;
                    let note = InsCcNote(json: JSON());
                    if let step = elem.dictionary?["step"]?.intValue {
                        note.step = step - 1;
                    }
                    if let octave = elem.dictionary?["octave"]?.intValue {
                        note.octave = octave;
                    }
                    if let alter = elem.dictionary?["alter"]?.intValue {
                        note.alter = alter;
                    }
                    if let acc = elem.dictionary?["acc"]?.dictionary?["acc"]?.string {
                        if acc == "Flat" {
                            note.accidental = "flat";
                        }else if acc == "Sharp" {
                            note.accidental = "sharp";
                        }else if acc == "Natural" {
                            note.accidental = "natural";
                        }
                    }
                    if let array = elem.dictionary?["pairs"]?.array {
                        for json in array {
                            if let type = json["type"].string {
                                if type == "tied" {
                                    note.tiedStart = "start";
                                }else if type == "tremolo" {
                                    note.tremolo = json["num"].intValue;
                                    let x1 = json["x1"].doubleValue;
                                    let x2 = json["x2"].doubleValue;
                                    if x1 <= note.x {
                                        note.tremoloType = "single";
                                    }else{
                                        note.tremoloType = "start";
                                        note.tremoloX2 = x2;
                                    }
                                }else if type == "wavy-line" {
                                    note.wavyLine = true;
                                }else if type == "tuplet" {
                                    note.tuplet = json["value"].intValue;
                                    note.isTupletUp = json["up"].boolValue;
                                }else if type == "slide" {
                                    note.isSlideStart = true;
                                }else if type == "slur" {
                                    note.slur = "start";
                                    let x1 = json["x1"].doubleValue;
                                    let x2 = json["x2"].doubleValue;
                                    note.slurStopx = x1 + x2 + note.x;
                                }else if type == "glissando" {
                                    note.isGlissandoStart = true;
                                    let x1 = json["x1"].doubleValue;
                                    let x2 = json["x2"].doubleValue;
                                    note.glissandoStopX = x2 + note.x;
                                }
                            }
                        }
                    }
                    if let tied = elem.dictionary?["tied"]?.string {
                        if tied == "end" {
                            note.tiedStop = "stop";
                        }
                    }
                    
                    if let id = elem.dictionary?["id"]?.string {
                        note.id = id;
                    }
                    if let line = elem.dictionary?["line"]?.intValue {
                        note.line = line;
                    }
                    if let y = elem.dictionary?["y"]?.intValue {
                        note.y = y;
                    }
                    self.chordNotes.append(note);
                }
            }
        }
        
        if let slurString = json["slur"].string {
            if slurString == "R" {
                self.slur = "stop";
            }else if slurString == "L" {
                self.slur = "start";
            }
        }
        
        if let type = json["stem"].dictionary?["type"]?.string {
            self.stemType = type;
        }
        if let type = json["rest"].dictionary?["nums"]?.intValue , type > 0 {
            self.rest = true;
            if self.duration > Double(type) {
                self.duration = Double(type);
            }
            self.octave = 0;
            self.step = 1;
            
        }
        
        if let restDic = json["rest"].dictionary {
            if let array = restDic["pairs"]?.array {
                for json in array {
                    if let type = json["type"].string {
                        if type == "tied" {
                            self.tiedStart = "start";
                        }else if type == "tremolo" {
                            self.tremolo = json["num"].intValue;
                        }else if type == "wavy-line" {
                            self.wavyLine = true;
                        }else if type == "tuplet" {
                            self.tuplet = json["value"].intValue;
                            self.isTupletUp = json["up"].boolValue;
                        }else if type == "slide" {
                            self.isSlideStart = true;
                        }else if type == "slur" {
                            self.slur = "start";
                            let x1 = array.first?.dictionary?["x1"]?.doubleValue ?? 0;
                            let x2 = array.first?.dictionary?["x2"]?.doubleValue ?? 0;
                            self.slurStopx = x1 + x2 + self.x;
                        }else if type == "glissando" {
                            self.isGlissandoStart = true;
                            let x1 = array.first?.dictionary?["x1"]?.doubleValue ?? 0;
                            let x2 = array.first?.dictionary?["x2"]?.doubleValue ?? 0;
                            self.glissandoStopX = x2 + self.x;
                        }
                    }
                }
            }
        }
        
        
        if let inbeam = json["inbeam"].bool {
            self.inbeam = inbeam;
        }
        if var beams = json["beams"].array {
            if beams.count != 0 {
                for beam in beams {
                    self.beamType.append((beam["i"].intValue + 1 , 0, beam["n2"].intValue));
                }
            }
        }
        
        if let arts = json["arts"].array {
            for art in arts {
                if art["type"].stringValue == "arpeggiate" {
                    self.arpeggiate = true;
                }else if art["type"].stringValue == "fermata" {
                    self.fermata = true;
                }else if art["type"].stringValue == "accent" {
                    self.accent = true;
                }else if art["type"].stringValue == "staccato"  {
                    self.articulations = true;
                }else if art["type"].stringValue == "fingering" {
                    self.fingeringArray.append(art["val"].stringValue);
                }else if art["type"].stringValue == "detached-legato" {
                    self.detachedLegato = true;
                }else if art["type"].stringValue == "string" {
                    self.string = 0;
                }else if art["type"].stringValue == "tenuto" {
                    self.tenuto = true;
                }else if art["type"].stringValue == "accent_staccato" {
                    self.accent = true;
                    self.articulations = true;
                }else if art["type"].stringValue == "inverted-mordent" {
                    self.invertedMordent = true;
                }else if art["type"].stringValue == "trill-mark" {
                    self.trillmark = true;
                }else if art["type"].stringValue == "turn" {
                    self.isTurn = true;
                }
              
            }
        }
        
        if let slash = json["grace"].dictionary?["slash"]?.boolValue {
            if slash {
                self.isGraceSlash = 2;
            }else {
                self.isGraceSlash = 1;
            }
        }
        
        if let lyricsArray = json["lyrics"].array {
            for lyricJson in lyricsArray {
                let string = lyricJson["text"].stringValue;
                let y = lyricJson["param"].dictionary?["y"]?.doubleValue ?? 0
                self.lyrics.append((string , y));
            }
        }
        
    }
    
    
}
